package edu.hawaii.senin.iclouds.plotting;

import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.File;
import java.io.FileReader;
import java.io.FileWriter;
import java.io.IOException;
import java.util.TreeMap;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

import edu.hawaii.senin.iclouds.util.TextUtils;

/**
 * Parses the log in order to get Ozone statistics.
 * 
 * @author Pavel Senin.
 * 
 */
public class UltraParserO3 {

  /* the population-related variables */
  static final Pattern accretionEventPattern = Pattern
      .compile("case_1:\\saccretion\\sevent:\\s[\\d]*");
  static final Pattern cascadeEventPattern = Pattern
      .compile("case_2:\\saccretion\\sevent:\\s[\\d]*");
  // private final Pattern cascadeEventPattern = Pattern.compile("Accretion\\sevent:\\s[\\d]*,");

  // private final Pattern grainPopulationSizePattern = Pattern
  // .compile("grain\\spopSize:\\s[\\d]*\\s");
  static final Pattern activePopulationPattern = Pattern.compile("surface:[\\w\\s]*\\sburied:");
  static final Pattern buriedPopulationPattern = Pattern.compile("buried:\\s");

  /**
   * @param args argument 1 = input log in txt file, argument2 would be output in csv format.
   */
  public static void main(String[] args) {
    String inputFname = args[0];
    String outFname = args[1];
    try {
      BufferedReader in = new BufferedReader(new FileReader(new File(inputFname)));
      BufferedWriter out = new BufferedWriter(new FileWriter(new File(outFname)));

      String cLine = null;

      Long lastKey = 0L;

      while ((cLine = in.readLine()) != null) {
        TextUtils.chomp(cLine);

        Matcher m = null;
        String tmp = null;
        Long accretionEvent = 0L;

        m = cascadeEventPattern.matcher(cLine);
        if (m.find()) {
          tmp = cLine.substring(m.start(), m.end());
          accretionEvent = Long.valueOf(tmp.substring("case_2: accretion event: ".length(), tmp
              .length()));
          while (lastKey >= accretionEvent) {
            accretionEvent += 1;
          }
        }

        if (accretionEvent != 0) {

          Long O3_active = 0L;
          Long O3_buried = 0L;

          StringBuilder str = new StringBuilder(200);
          m = activePopulationPattern.matcher(cLine);
          if (m.find()) {
            tmp = cLine.substring(m.start() + "surface: ".length(), m.end() - " buried:".length());
            TreeMap<String, Long> tmpPop = new TreeMap<String, Long>();
            String[] breakedLine = tmp.split("\\s+");
            if (breakedLine.length >= 2) {
              for (int i = 0; i < breakedLine.length; i += 2) {
                String specieName = TextUtils.chomp(breakedLine[i]);
                Long numValue = Long.valueOf(TextUtils.chomp(breakedLine[i + 1]));
                tmpPop.put(specieName, numValue);
              }
            }
            if (tmpPop.containsKey("O3")) {
              O3_active = Long.valueOf(tmpPop.get("O3"));
              str.append(new String(accretionEvent + ", " + tmpPop.get("O3") + ", "));
            }
            else {
              str.append(new String(accretionEvent + ", 0, "));
            }
          }

          m = buriedPopulationPattern.matcher(cLine);
          if (m.find()) {
            tmp = cLine.substring(m.start() + "buried: ".length());
            TreeMap<String, Long> tmpPop = new TreeMap<String, Long>();
            String[] breakedLine = tmp.split("\\s+");
            if (breakedLine.length >= 2) {
              for (int i = 0; i < breakedLine.length; i += 2) {
                String specieName = TextUtils.chomp(breakedLine[i]);
                Long numValue = Long.valueOf(TextUtils.chomp(breakedLine[i + 1]));
                tmpPop.put(specieName, numValue);
              }
            }
            if (tmpPop.containsKey("O3")) {
              O3_buried = Long.valueOf(tmpPop.get("O3"));
              str.append(tmpPop.get("O3").toString());
            }
            else {
              str.append(new String(" 0"));
            }
          }
          if (str.length() > 0) {
            if ((O3_active > 10000L) && (O3_active < 12000)) {
              out.write(str.toString() + "\n");
            }
            else if (O3_buried > 22000) {
              break;
            }
          }
        }

      }
      in.close();
      out.flush();
      out.close();

    }
    catch (IOException e) {
      // TODO Auto-generated catch block
      e.printStackTrace();
    }
  }

}
